#
# Sorto, the sorting game
# Copyright (C) 2012 Ralph Preston
# ralph.preston@gmail.com
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to:
#
# Free Software Foundation, Inc.
# 51 Franklin Street, Fifth Floor
# Boston, MA 02110-1301
# USA.
#
import sys

from sorto_board       import SortoBoard
from sorto_base_view   import SortoBaseView
from sorto_base_player import SortoBasePlayer

class SortoPlayer(SortoBasePlayer):
    """
    This class inherits from SortoBasePlayer which makes available a
    board and counters.
    
    self._board is the game board. Set by the controller at the start
    of every game. Initial value is [SortoBoard.EMPTY]*36

    self._available_counters are the counters to place. Set by the
    controller during game play. Is a list of integers. Ex: [1,2,9]
    """
    def __init__(self, view):
        SortoBasePlayer.__init__(self, name='Player X', 
                                 seed=1, view=view, color='#f52887')
        return

    def new_game(self, game_number):
        SortoBasePlayer.new_game(self, game_number)
        """
        The controller calls this at the start of every game. Use as
        you will.
        """
        return

    def game_over(self):
        SortoBasePlayer.game_over(self)
        """
        Yes, this is called when the game is over. When any player in
        the game satisfies the winning condition, or the round count
        reaches a threshold, this method is called on all players.
        """
        return

    def examine_table(self, players_boards, players_counters):
        """
        The player may view the table and examine other players boards
        and counters, in case this effects their decisions.

        players_boards is a dictionary using the players name as a key
        and a boards as the value. Ex: 
        { 
          'Player 1' : [None, None, 3, ... , None, None], 
          'Player 2' : [None, None, 3, ... , None, None], 
        }

        players_counters is a dictionary using the players name as a
        key and the value is a list of available counters.
        { 
          'Player 1' : [ 3, 5, 9 ], 
          'Player 2' : [ 3, 5, 9 ],
        }
        """
        return

    def play_roll(self, roll):
        """
        After receiving a game board and starting counters the
        controller begins generating a roll from 1 to 20.  The player
        must place/move one of their counters onto the board in the
        square rolled. If there are available counters the player must
        place one of them on the location rolled.

        The roll is an integer value from 1 to 20.
        """
        if self._view:
            self._view.display_text("%s playing roll %d" % (self._name,roll))
            pass

        space = None
        while space is None and not self._abort:
            if len(self._available_counters) > 0:
                counter_from = SortoBaseView.OFF_BOARD_COUNTER
            else:
                counter_from = SortoBaseView.BOARD_COUNTER
                pass

            counter = self._view.choose_counter(self._name, counter_from)
            if self._abort: return
            if counter_from is SortoBaseView.BOARD_COUNTER:
                counter_index = self._board.index(counter)
                self._board.remove_counter(counter)
                pass
            space = self._place_counter(roll, counter)
            if self._abort: return
            if space is None:
                # If the space wasn't a legal placement tell the view
                # to put the counter back.
                self._view.undo_place_counter()
                if counter_from is SortoBaseView.BOARD_COUNTER:
                    # If the counter wasn't placed legally put the counter back
                    self._board[counter_index] = counter
                    pass
                pass
            else:
                self._view.accept_place_counter()
                pass
            pass

        if self._abort: return

        if counter_from is SortoBaseView.OFF_BOARD_COUNTER:
            self._available_counters.remove(counter)
            pass

        # Place the counter on the board
        self._board[space] = counter

        return

    def _place_counter(self, roll, counter):
        board = self._board

        legal_places = board.legal_places_for_roll_and_counter(roll, counter)

        location_index = self._view.place_counter(self._name)

        if location_index in legal_places:
            return location_index
        return None
    
    pass # End of class SortoPlayer

